//
// SoapTrace.Net - A soap message monitoring utility.
//
// Copyright (C) 2004 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using NUnit.Framework;
using SoapTrace.Core.Formatters;
using SoapTrace.Tests.Utils;
using SoapTrace.Tests.Config;
using System;
using System.Configuration;
using System.IO;

namespace SoapTrace.Tests
{
	/// <summary>
	/// Tests the parsing of a Document literal wsdl string.
	/// </summary>
	[ TestFixture ]
	public class MathsWebServiceTestFixture
	{
		/// <summary>
		/// The web service read from the wsdl file.
		/// </summary>
		WebService WebService = null;
		
		/// <summary>
		/// The web service that we expect to be
		/// read from the wsdl.
		/// </summary>
		WebService ExpectedWebService = null;
		
		/// <summary>
		/// Initialises each test.
		/// </summary>
		[ SetUp ]
		public void Init( )
		{
			WebServicesDescriptionLanguageFile Wsdl = new WebServicesDescriptionLanguageFile( );
			Wsdl.Load( new StringReader( GetWsdl( ) ) );
			          
			WebService = Wsdl.WebService;
						
			InitExpectedWebService( );
		}
		
		/// <summary>
		/// Tests that the web service name is extracted correctly.
		/// </summary>
		[ Test ]
		public void WebServiceName( )
		{
			Assert.AreEqual( ExpectedWebService.Name, WebService.Name, "Web service name is incorrect." );
		}
		
		/// <summary>
		/// Check the uri extracted from the wsdl file is correct.
		/// </summary>
		[ Test ]
		public void WebServiceUri( )
		{
			Assert.AreEqual( ExpectedWebService.Uri, WebService.Uri,
				"Web service uri is incorrect." );
		}
		
		/// <summary>
		/// Tests that the web service operations have been extracted.
		/// </summary>
		[ Test ]
		public void Operations( )
		{
			Assert.AreEqual( ExpectedWebService.Operations.Count, 
				WebService.Operations.Count, 
				"Web service count is incorrect." );
			
			for( int i = 0; i < ExpectedWebService.Operations.Count; ++i )
			{
				WebServiceOperation ExpectedOperation = ExpectedWebService.Operations[ i ];
				WebServiceOperation ActualOperation = WebService.Operations[ i ];
				
				Assert.AreEqual( ExpectedOperation.Name, 
				                ActualOperation.Name, 
				                "Web service operation name mismatch" );
				
				Assert.AreEqual( ExpectedOperation.Parameters.Count, 
				                ActualOperation.Parameters.Count,
				                String.Concat( "Web service params count mismatch.  Name=",
				                              ExpectedOperation.Name ) );
				
				WebServiceTestUtility.CompareParameters( ExpectedOperation, ActualOperation, "Param mismatch.  Name=" + ExpectedOperation.Name );
			
				WebServiceTestUtility.CompareReturnValue( ExpectedOperation, ActualOperation, "Return value mismatch.  Name=" + ExpectedOperation.Name );
			}
		}
		
		/// <summary>
		/// Sets up the <see cref="ExpectedWebService"/>.
		/// </summary>
		private void InitExpectedWebService( )
		{
			ExpectedWebService = new WebService( );
			
			ExpectedWebService.Name = "Maths";
			ExpectedWebService.Uri = "/Maths.asmx";
			
			// Set up operation
			ExpectedWebService.Operations.Add( GetAddOperation( ) );
			ExpectedWebService.Operations.Add( GetMultiplyOperation( ) );
			ExpectedWebService.Operations.Add( GetAddSetOperation( ) );
			ExpectedWebService.Operations.Add( GetMultiplyListOperation( ) );
			ExpectedWebService.Operations.Add( GetSendOperation( ) );
		}
		
		/// <summary>
		/// Creates a <see cref="WebServiceOperation"/> for the
		/// Maths.Add web service.
		/// </summary>
		/// <returns>A <see cref="WebServiceOperation"/>.</returns>
		private WebServiceOperation GetAddOperation( )
		{
			WebServiceOperation Operation = new WebServiceOperation( );
			Operation.Name = "Add";
			
			WebServiceParameter Param = new WebServiceParameter( );
			Param.Name = "value1";
			Param.ParameterType = "int";
			
			Operation.Parameters.Add( Param );
			
			Param = new WebServiceParameter( );
			Param.Name = "value2";
			Param.ParameterType = "int";			
			
			Operation.Parameters.Add( Param );
			
			WebServiceReturnValue ReturnValue = new WebServiceReturnValue( );
			ReturnValue.Name = "AddResult";
			ReturnValue.ParameterType = "int";

			Operation.ReturnValue = ReturnValue;
			
			return Operation;
		}
		
	
		/// <summary>
		/// Creates a <see cref="WebServiceOperation"/> for the
		/// Maths.Send web service.
		/// </summary>
		/// <returns>A <see cref="WebServiceOperation"/>.</returns>
		private WebServiceOperation GetSendOperation( )
		{
			WebServiceOperation Operation = new WebServiceOperation( );
			Operation.Name = "Send";
			
			WebServiceParameter Param = new WebServiceParameter( );
			Param.Name = "value";
			Param.ParameterType = "int";
			
			Operation.Parameters.Add( Param );
					
			return Operation;
		}		
		
		/// <summary>
		/// Creates a <see cref="WebServiceOperation"/> for the
		/// Maths.Multiply web service.
		/// </summary>
		/// <returns>A <see cref="WebServiceOperation"/>.</returns>
		private WebServiceOperation GetMultiplyOperation( )
		{
			WebServiceOperation Operation = new WebServiceOperation( );
			Operation.Name = "Multiply";
			
			WebServiceParameter Param = new WebServiceParameter( );
			Param.Name = "value1";
			Param.ParameterType = "int";
			
			Operation.Parameters.Add( Param );
			
			Param = new WebServiceParameter( );
			Param.Name = "value2";
			Param.ParameterType = "int";			
			
			Operation.Parameters.Add( Param );
			
			WebServiceReturnValue ReturnValue = new WebServiceReturnValue( );
			ReturnValue.Name = "MultiplyResult";
			ReturnValue.ParameterType = "int";

			Operation.ReturnValue = ReturnValue;
			
			return Operation;
		}	
		
		/// <summary>
		/// Creates a <see cref="WebServiceOperation"/> for the
		/// Maths.AddSet web service.
		/// </summary>
		/// <returns>A <see cref="WebServiceOperation"/>.</returns>
		private WebServiceOperation GetAddSetOperation( )
		{
			WebServiceOperation Operation = new WebServiceOperation( );
			Operation.Name = "AddSet";
			
			WebServiceParameter Param = new WebServiceParameter( );
			Param.Name = "values";
			Param.ParameterType = "int.array";
			
			Operation.Parameters.Add( Param );
					
			WebServiceReturnValue ReturnValue = new WebServiceReturnValue( );
			ReturnValue.Name = "AddSetResult";
			ReturnValue.ParameterType = "int";

			Operation.ReturnValue = ReturnValue;
			
			return Operation;
		}		
		
	/// <summary>
		/// Creates a <see cref="WebServiceOperation"/> for the
		/// Maths.MultiplyList web service.
		/// </summary>
		/// <returns>A <see cref="WebServiceOperation"/>.</returns>
		private WebServiceOperation GetMultiplyListOperation( )
		{
			WebServiceOperation Operation = new WebServiceOperation( );
			Operation.Name = "MultiplyList";
			
			WebServiceParameter Param = new WebServiceParameter( );
			Param.Name = "values";
			Param.ParameterType = "int.array";
			
			Operation.Parameters.Add( Param );
			
			Param = new WebServiceParameter( );
			Param.Name = "factor";
			Param.ParameterType = "int";
			
			Operation.Parameters.Add( Param );

			WebServiceReturnValue ReturnValue = new WebServiceReturnValue( );
			ReturnValue.Name = "MultiplyListResult";
			ReturnValue.ParameterType = "int.array";

			Operation.ReturnValue = ReturnValue;
			
			return Operation;
		}			
		
		/// <summary>
		/// Gets the document literal wsdl string.
		/// </summary>
		/// <returns>A wsdl string.</returns>
		private string GetWsdl( )
		{
			return "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" +
					"<definitions xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:s=\"http://www.w3.org/2001/XMLSchema\" xmlns:s0=\"http://soaptrace.net/webservices\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tm=\"http://microsoft.com/wsdl/mime/textMatching/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" targetNamespace=\"http://soaptrace.net/webservices\" xmlns=\"http://schemas.xmlsoap.org/wsdl/\">\r\n" +
					"  <types>\r\n" +
					"    <s:schema elementFormDefault=\"qualified\" targetNamespace=\"http://soaptrace.net/webservices\">\r\n" +
					"      <s:element name=\"Add\">\r\n" +
					"        <s:complexType>\r\n" +
					"          <s:sequence>\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"value1\" type=\"s:int\" />\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"value2\" type=\"s:int\" />\r\n" +
					"          </s:sequence>\r\n" +
					"\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"      <s:element name=\"AddResponse\">\r\n" +
					"        <s:complexType>\r\n" +
					"          <s:sequence>\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"AddResult\" type=\"s:int\" />\r\n" +
					"          </s:sequence>\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"\r\n" +
					"      <s:element name=\"Multiply\">\r\n" +
					"        <s:complexType>\r\n" +
					"          <s:sequence>\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"value1\" type=\"s:int\" />\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"value2\" type=\"s:int\" />\r\n" +
					"          </s:sequence>\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"      <s:element name=\"MultiplyResponse\">\r\n" +
					"\r\n" +
					"        <s:complexType>\r\n" +
					"          <s:sequence>\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"MultiplyResult\" type=\"s:int\" />\r\n" +
					"          </s:sequence>\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"      <s:element name=\"AddSet\">\r\n" +
					"        <s:complexType>\r\n" +
					"          <s:sequence>\r\n" +
					"\r\n" +
					"            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"values\" type=\"s0:ArrayOfInt\" />\r\n" +
					"          </s:sequence>\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"      <s:complexType name=\"ArrayOfInt\">\r\n" +
					"        <s:sequence>\r\n" +
					"          <s:element minOccurs=\"0\" maxOccurs=\"unbounded\" name=\"int\" type=\"s:int\" />\r\n" +
					"        </s:sequence>\r\n" +
					"      </s:complexType>\r\n" +
					"\r\n" +
					"      <s:element name=\"AddSetResponse\">\r\n" +
					"        <s:complexType>\r\n" +
					"          <s:sequence>\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"AddSetResult\" type=\"s:int\" />\r\n" +
					"          </s:sequence>\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"      <s:element name=\"MultiplyList\">\r\n" +
					"        <s:complexType>\r\n" +
					"\r\n" +
					"          <s:sequence>\r\n" +
					"            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"values\" type=\"s0:ArrayOfInt\" />\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"factor\" type=\"s:int\" />\r\n" +
					"          </s:sequence>\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"      <s:element name=\"MultiplyListResponse\">\r\n" +
					"        <s:complexType>\r\n" +
					"          <s:sequence>\r\n" +
					"\r\n" +
					"            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"MultiplyListResult\" type=\"s0:ArrayOfInt\" />\r\n" +
					"          </s:sequence>\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"      <s:element name=\"Send\">\r\n" +
					"        <s:complexType>\r\n" +
					"          <s:sequence>\r\n" +
					"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"value\" type=\"s:int\" />\r\n" +
					"          </s:sequence>\r\n" +
					"\r\n" +
					"        </s:complexType>\r\n" +
					"      </s:element>\r\n" +
					"      <s:element name=\"SendResponse\">\r\n" +
					"        <s:complexType />\r\n" +
					"      </s:element>\r\n" +
					"    </s:schema>\r\n" +
					"  </types>\r\n" +
					"  <message name=\"AddSoapIn\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:Add\" />\r\n" +
					"\r\n" +
					"  </message>\r\n" +
					"  <message name=\"AddSoapOut\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:AddResponse\" />\r\n" +
					"  </message>\r\n" +
					"  <message name=\"MultiplySoapIn\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:Multiply\" />\r\n" +
					"  </message>\r\n" +
					"  <message name=\"MultiplySoapOut\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:MultiplyResponse\" />\r\n" +
					"\r\n" +
					"  </message>\r\n" +
					"  <message name=\"AddSetSoapIn\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:AddSet\" />\r\n" +
					"  </message>\r\n" +
					"  <message name=\"AddSetSoapOut\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:AddSetResponse\" />\r\n" +
					"  </message>\r\n" +
					"  <message name=\"MultiplyListSoapIn\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:MultiplyList\" />\r\n" +
					"\r\n" +
					"  </message>\r\n" +
					"  <message name=\"MultiplyListSoapOut\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:MultiplyListResponse\" />\r\n" +
					"  </message>\r\n" +
					"  <message name=\"SendSoapIn\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:Send\" />\r\n" +
					"  </message>\r\n" +
					"  <message name=\"SendSoapOut\">\r\n" +
					"    <part name=\"parameters\" element=\"s0:SendResponse\" />\r\n" +
					"\r\n" +
					"  </message>\r\n" +
					"  <portType name=\"MathsSoap\">\r\n" +
					"    <operation name=\"Add\">\r\n" +
					"      <input message=\"s0:AddSoapIn\" />\r\n" +
					"      <output message=\"s0:AddSoapOut\" />\r\n" +
					"    </operation>\r\n" +
					"    <operation name=\"Multiply\">\r\n" +
					"      <input message=\"s0:MultiplySoapIn\" />\r\n" +
					"      <output message=\"s0:MultiplySoapOut\" />\r\n" +
					"\r\n" +
					"    </operation>\r\n" +
					"    <operation name=\"AddSet\">\r\n" +
					"      <input message=\"s0:AddSetSoapIn\" />\r\n" +
					"      <output message=\"s0:AddSetSoapOut\" />\r\n" +
					"    </operation>\r\n" +
					"    <operation name=\"MultiplyList\">\r\n" +
					"      <input message=\"s0:MultiplyListSoapIn\" />\r\n" +
					"      <output message=\"s0:MultiplyListSoapOut\" />\r\n" +
					"    </operation>\r\n" +
					"\r\n" +
					"    <operation name=\"Send\">\r\n" +
					"      <input message=\"s0:SendSoapIn\" />\r\n" +
					"      <output message=\"s0:SendSoapOut\" />\r\n" +
					"    </operation>\r\n" +
					"  </portType>\r\n" +
					"  <binding name=\"MathsSoap\" type=\"s0:MathsSoap\">\r\n" +
					"    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\" />\r\n" +
					"    <operation name=\"Add\">\r\n" +
					"      <soap:operation soapAction=\"http://soaptrace.net/webservices/Add\" style=\"document\" />\r\n" +
					"\r\n" +
					"      <input>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </input>\r\n" +
					"      <output>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </output>\r\n" +
					"    </operation>\r\n" +
					"    <operation name=\"Multiply\">\r\n" +
					"      <soap:operation soapAction=\"http://soaptrace.net/webservices/Multiply\" style=\"document\" />\r\n" +
					"\r\n" +
					"      <input>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </input>\r\n" +
					"      <output>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </output>\r\n" +
					"    </operation>\r\n" +
					"    <operation name=\"AddSet\">\r\n" +
					"      <soap:operation soapAction=\"http://soaptrace.net/webservices/AddSet\" style=\"document\" />\r\n" +
					"\r\n" +
					"      <input>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </input>\r\n" +
					"      <output>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </output>\r\n" +
					"    </operation>\r\n" +
					"    <operation name=\"MultiplyList\">\r\n" +
					"      <soap:operation soapAction=\"http://soaptrace.net/webservices/MultiplyList\" style=\"document\" />\r\n" +
					"\r\n" +
					"      <input>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </input>\r\n" +
					"      <output>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </output>\r\n" +
					"    </operation>\r\n" +
					"    <operation name=\"Send\">\r\n" +
					"      <soap:operation soapAction=\"http://soaptrace.net/webservices/Send\" style=\"document\" />\r\n" +
					"\r\n" +
					"      <input>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </input>\r\n" +
					"      <output>\r\n" +
					"        <soap:body use=\"literal\" />\r\n" +
					"      </output>\r\n" +
					"    </operation>\r\n" +
					"  </binding>\r\n" +
					"  <service name=\"Maths\">\r\n" +
					"\r\n" +
					"    <port name=\"MathsSoap\" binding=\"s0:MathsSoap\">\r\n" +
					"      <soap:address location=\"http://127.0.0.1/Maths.asmx\" />\r\n" +
					"    </port>\r\n" +
					"  </service>\r\n" +
					"</definitions>";
		}
	}
}
